package com.jin.webvideo.config.filter.access.handler;

import com.jin.webvideo.base.util.CollectionsUtil;
import com.jin.webvideo.config.filter.access.AccessControl;
import com.jin.webvideo.config.filter.access.GlobalStore;
import com.jin.webvideo.entity.ForbidRecord;
import com.jin.webvideo.entity.SessionStore;
import com.jin.webvideo.service.AccessServer;
import com.jin.webvideo.util.SimpleTemplateParser;
import com.jin.webvideo.util.base.StringUtil;
import com.jin.webvideo.base.util.SystemInfo;
import com.jin.webvideo.util.base.URLUtil;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

/**
 * ip黑名单处理
 */
@Data
public class InetAddressAccessHandler implements AccessHandler {
    @Autowired
    private AccessServer accessServer;
    @Autowired
    private SimpleTemplateParser parser;
    private List<String> resourceType;

    public InetAddressAccessHandler() {
        resourceType = Collections.unmodifiableList(List.of("js", "css", "jpg", "png", "ico"));
    }

    @Override
    public boolean handle(GlobalStore globalStore, SessionStore store, HttpServletRequest request, AccessControl.Access access, HandlerChain handlerChain) {
        String uri = request.getRequestURI();
        String address = request.getRemoteAddr();

        List<ForbidRecord> records = accessServer.findRecordBySpecificAddress(address, SystemInfo.nowSecond());
        // 查找封禁记录
        ForbidRecord record = CollectionsUtil.first(records, (r) -> StringUtil.match(r.getVal(), uri));
        if (record == null) {
            return handlerChain.doHandle(access, globalStore, request, store);
        }
        // 静态资源直接返回不添加提示信息
        String suffixName = URLUtil.fileType(uri);
        if (suffixName != null && resourceType.contains(suffixName.toLowerCase(Locale.ROOT))) {
            AccessControl.Access.forbid(access, 403, "");
            return true;
        }
        // 添加封禁信息
        parser.setVariables(BeanMap.create(record));
        String msg = parser.getValue(record.getInformation(), String.class);
        AccessControl.Access.forbid(access, 403, msg);
        return true;
    }

    @Override
    public int order() {
        return Integer.MIN_VALUE;
    }
}
